<?php

namespace App\Service\Cruise\Check;

use App\Library\Rms\RmsUserApi;
use App\Models\Common\FsCompanyModel;
use App\Models\Common\FsCompanyRoleMappingModel;
use App\Models\Common\FsCompanySecondDepartmentModel;
use App\Models\Common\FsCompanyUserMappingModel;
use App\Models\Common\FsCompanyUserModel;
use App\Models\Common\FsOrganizationModel;
use App\Models\Cruise\CruiseCheckCompanyModel;
use App\Models\Cruise\CruiseCheckDetailModel;
use App\Models\Cruise\CruiseCheckErrorModel;
use App\Models\Cruise\CruiseOrderModel;
use App\Remote\Rms\RmsUserRemote;
use App\Service\BaseService;
use Carbon\Carbon;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;

class CruiseCheckCompanyService extends BaseService
{

    /**
     * 选择供应商
     * @return array
     */
    public static function frontCompany(): array
    {
        $organizationNames = FsOrganizationModel::query()->pluck('name', 'id');

        //不显示已选择的供应商
        //获得已有的供应商
        $cruiseCheckCompany = CruiseCheckCompanyModel::query()->pluck('fsCompanyId')->toArray();  //改用字查询
        $list               = [];
        FsCompanySecondDepartmentModel::query()
            ->where('businessType', FsCompanySecondDepartmentModel::BUSINESS_TYPE_CHECK)
            ->with(['fsCompanyRel'])
            ->get()
            ->each(function (FsCompanySecondDepartmentModel $fsCompanySecondDepartmentModel) use (&$list, $cruiseCheckCompany, $organizationNames) {

                $organizationId = $fsCompanySecondDepartmentModel->fsCompanyRel->organizationId;
                $organizationName = $organizationNames[$organizationId] ?? '';

                $list[] = [
                    'id'       => object_get($fsCompanySecondDepartmentModel, 'fsCompanyRel.id', 0),
                    'name'     => $organizationName . '-'. object_get($fsCompanySecondDepartmentModel, 'fsCompanyRel.name', '-'),
                    'disabled' => in_array(object_get($fsCompanySecondDepartmentModel, 'fsCompanyRel.id', 0), $cruiseCheckCompany)
                ];
            });

        return $list;
    }

    /**
     * 选择用户信息
     * @param $id
     * @return array[]
     */
    public static function frontUserInfo($id): array
    {
        $userInfo = [];
        FsCompanyUserMappingModel::query()
            ->where('fsCompanyId', $id)
            ->where('businessType', FsCompanyUserMappingModel::BUSINESS_TYPE_CRUISE_CHECK)
            ->with(['fsCompanyUserRel'])
            ->each(function (FsCompanyUserMappingModel $fsCompanyUserMappingModel) use (&$userInfo) {
                if (null != $fsCompanyUserMappingModel->fsCompanyUserRel) {
                    $userInfo[] = [
                        'name'             => $fsCompanyUserMappingModel->fsCompanyUserRel->name,
                        'phone'            => $fsCompanyUserMappingModel->fsCompanyUserRel->phone,
                        'companyManagerId' => $fsCompanyUserMappingModel->fsCompanyUserRel->rmsUserId,
                    ];
                }
            });
        return ['userInfo' => $userInfo];
    }

    /**
     * 添加&修改 供应商配置
     * @param $id
     * @param $fsCompanyId
     * @param $kfManagerId
     * @param $companyManagerId
     * @return void
     */
    public static function save($id, $fsCompanyId, $kfManagerId, $companyManagerId)
    {
        if ($id) {
            $cruiseCheckCompanyModel = CruiseCheckCompanyModel::query()->find($id);
            if (null == $cruiseCheckCompanyModel) {
                self::throwErr('修改失败');
            }
        } else {
            $cruiseCheckCompanyModel = new CruiseCheckCompanyModel();
        }
        $cruiseCheckCompanyModel->fsCompanyId      = $fsCompanyId;
        $cruiseCheckCompanyModel->kfManagerId      = $kfManagerId;
        $cruiseCheckCompanyModel->companyManagerId = $companyManagerId;
        $cruiseCheckCompanyModel->status           = CruiseCheckCompanyModel::STATUS_ON;
        $cruiseCheckCompanyModel->save();

        // 清空缓存
        CruiseCheckCompanyModel::forgetCompanyListsCache();
    }

    /**
     * 删除供应商配置
     * @param $cruiseCheckCompanyId
     * @return void
     */
    public static function delete($cruiseCheckCompanyId)
    {
        CruiseCheckCompanyModel::query()
            ->where('id', $cruiseCheckCompanyId)
            ->update([
                'isDeleted' => 1
            ]);

        // 清空缓存
        CruiseCheckCompanyModel::forgetCompanyListsCache();
    }

    /**
     * 修改供应商状态
     * @param $id
     * @param $status
     * @return void
     */
    public static function able($id, $status)
    {
        CruiseCheckCompanyModel::query()
            ->where('id', $id)
            ->update([
                'status' => $status
            ]);
        //控制任务
        if ($status == CruiseCheckCompanyModel::STATUS_OFF) {
            //停用
            CruiseOrderModel::query()
                ->where('cruiseCheckCompanyId', $id)
                ->whereIn('status', [CruiseOrderModel::STATUS_INIT, CruiseOrderModel::STATUS_NOT_SUBMIT, CruiseOrderModel::STATUS_NOT_REVIEW, CruiseOrderModel::STATUS_NOT_MODIFY, CruiseOrderModel::STATUS_WAIT_MODIFY_EXT, CruiseOrderModel::STATUS_COLLECTED])
                ->get()
                ->each(function (CruiseOrderModel $cruiseOrderModel) {
                    //作废订单
                    CruiseCheckTaskService::orderCancel($cruiseOrderModel->id, 0, false, CruiseCheckErrorModel::INVALID_TYPE_MISS, '', [], [CruiseOrderModel::STATUS_INIT, CruiseOrderModel::STATUS_NOT_SUBMIT, CruiseOrderModel::STATUS_NOT_REVIEW, CruiseOrderModel::STATUS_NOT_MODIFY, CruiseOrderModel::STATUS_WAIT_MODIFY_EXT, CruiseOrderModel::STATUS_COLLECTED]);
                    $cruiseOrderModel->isDeleted = 1;
                    $cruiseOrderModel->save();
                });
        } elseif ($status == CruiseCheckCompanyModel::STATUS_ON) {
            //启用
            CruiseOrderModel::query()
                ->where('cruiseCheckCompanyId', $id)
                ->withoutGlobalScope('isDel')
                ->where('status', CruiseOrderModel::STATUS_CLOSED)
                ->update([
                    'isDeleted' => 0,
                ]);
        }

        // 清空缓存
        CruiseCheckCompanyModel::forgetCompanyListsCache();
    }

    /**
     * 获取供应商配置详情
     * @param $id
     * @return array
     */
    public static function detail($id): array
    {
        $cruiseCheckCompanyModel = CruiseCheckCompanyModel::query()
            ->with(['fsCompanyRel', 'fsCompanyUserRel'])
            ->find($id);

        if (null == $cruiseCheckCompanyModel) {
            self::throwErr('查询信息不存在');
        }
        return [
            'fsCompanyId'      => $cruiseCheckCompanyModel->fsCompanyId,
            'fsCompanyName'    => (string)optional($cruiseCheckCompanyModel->fsCompanyRel)->name,
            'companyUserName'  => (string)optional($cruiseCheckCompanyModel->fsCompanyUserRel)->name,
            'companyUserPhone' => (string)optional($cruiseCheckCompanyModel->fsCompanyUserRel)->phone,
            'companyManagerId' => (int)optional($cruiseCheckCompanyModel->fsCompanyUserRel)->rmsUserId,
            'kfManagerId'      => $cruiseCheckCompanyModel->kfManagerId,
        ];
    }

    /**
     * 获得供应商配置列表
     * @param $pageSize
     * @param $pageNum
     * @param $companyId
     * @param $kfManagerId
     * @return array
     */
    public static function list($pageSize, $pageNum, $companyId, $kfManagerId): array
    {
        $paginator = CruiseCheckCompanyModel::query()
            ->when($companyId, function ($query) use ($companyId) {
                $query->where('id', $companyId);
            })
            ->when($kfManagerId, function ($query) use ($kfManagerId) {
                $query->where('kfManagerId', $kfManagerId);
            })
            ->with(['fsCompanyRel', 'fsCompanyUserRel'])
            ->paginate($pageSize, ['*'], 'pageNum', $pageNum);

        $userData = (new RmsUserApi())->getUserInfoByIds(array_merge($paginator->pluck('updatedByUid')->toArray(), $paginator->pluck('kfManagerId')->toArray()), ['id', 'username'])['data'] ?? [];
        $userList = array_column($userData, 'username', 'id');

        $organizationNames = FsOrganizationModel::query()->pluck('name', 'id');

        $list = $paginator->map(function (CruiseCheckCompanyModel $cruiseCheckCompanyModel) use ($userList, $organizationNames) {

            $organizationId = $cruiseCheckCompanyModel->fsCompanyRel->organizationId;
            $organizationName = $organizationNames[$organizationId] ?? '';

            return [
                'id'               => $cruiseCheckCompanyModel->id,
                'fsCompanyId'      => $cruiseCheckCompanyModel->fsCompanyId,
                'fsCompanyName'    => $organizationName . '-'. (string)optional($cruiseCheckCompanyModel->fsCompanyRel)->name,
                'companyUserName'  => (string)optional($cruiseCheckCompanyModel->fsCompanyUserRel)->name,
                'companyUserPhone' => (string)optional($cruiseCheckCompanyModel->fsCompanyUserRel)->phone,
                'companyManagerId' => (int)optional($cruiseCheckCompanyModel->fsCompanyUserRel)->rmsUserId,
                'kfManagerId'      => $cruiseCheckCompanyModel->kfManagerId,
                'kfManagerName'    => $userList[$cruiseCheckCompanyModel->kfManagerId] ?? '',
                'updatedByName'    => $userList[$cruiseCheckCompanyModel->updatedByUid] ?? '',
                'updatedTime'      => $cruiseCheckCompanyModel->updatedAt->toDateTimeString(),
                'status'           => $cruiseCheckCompanyModel->status,
                'statusText'       => CruiseCheckCompanyModel::STATUS_TEXT[$cruiseCheckCompanyModel->status] ?? '-',
            ];
        })->toArray();

        return [
            'list'     => $list,
            'count'    => $paginator->total(),
            'pageSize' => $pageSize,
            'pageNum'  => $pageNum,
        ];
    }


    /**
     * 供应商下拉
     * @return array
     */
    public static function selectCompany(): array
    {
        $organizationNames = FsOrganizationModel::query()->pluck('name', 'id');

        return [
            'list' => CruiseCheckCompanyModel::query()
                ->where('status', CruiseCheckCompanyModel::STATUS_ON)
                ->with(['fsCompanyRel'])
                ->get()
                ->map(function (CruiseCheckCompanyModel $cruiseCheckCompanyModel) use ($organizationNames) {

                    $organizationId = $cruiseCheckCompanyModel->fsCompanyRel->organizationId;
                    $organizationName = $organizationNames[$organizationId] ?? '';

                    return [
                        'id'   => $cruiseCheckCompanyModel->id,
                        'name' => $organizationName . '-'. $cruiseCheckCompanyModel->fsCompanyRel->name,
                    ];
                })->toArray()
        ];
    }


    /**
     * 通过用户ID获得供应商ID
     * @param int $userId
     * @return array
     */
    public static function getPowerList(int $userId): array
    {
        $companyIds = CruiseCheckCompanyModel::query()
            ->where('status', CruiseCheckCompanyModel::STATUS_ON)
            ->where('companyManagerId', $userId)
            ->pluck('id')
            ->toArray();

        if (!count($companyIds)) {
            return [-1];
        }

        return $companyIds;
    }


    /**
     * 获得公司员工列表
     * @param int $pageNum
     * @param int $pageSize
     * @param int $companyId
     * @param string $username
     * @param string $mobile
     * @return array
     */
    public static function staffList(int $pageNum, int $pageSize, int $companyId, string $username, string $mobile): array
    {
        $paginate = FsCompanyUserModel::query()
            // ->join('fs_company', 'fs_company.departmentId', '=', 'fs_company_users.supplierDepartmentId')
            // ->where('fs_company.organizationId', FsCompanyModel::WEB_ORGANIZATION_ID)
            //->where('ext', FsCompanyUserModel::EXT_OUT)
            ->where('source', FsCompanyUserModel::SOURCE_QUALITY_CONTROL)
            ->when(strlen($username), function ($query) use ($username) {
                $query->where('name', 'like', "%$username%");
            })
            ->when(strlen($mobile), function ($query) use ($mobile) {
                $query->where('phone', $mobile);
            })
            ->when($companyId, function ($query) use ($companyId){
                $query->whereRaw("rmsUserId in (select rmsUserId from fs_company_user_mappings where fsCompanyId = {$companyId})");
            })
            //->whereIn('rmsUserId', self::getQualityControlStaffList($companyId))
            ->groupBy('rmsUserId')
            ->orderByDesc('id')
            ->with(['fsCompanyUserMappingRel'])
            ->paginate($pageSize, ["*"], "pageNum", $pageNum);

        // 获得用户状态
        $userInfo = array_column((new RmsUserApi())->getUserInfoByIds($paginate->pluck('rmsUserId')->toArray(), ['id', 'username', 'mobile', 'status'])['data'] ?? [], null, 'id');

        // 获得companyIds
        $companyIds = [];
        $qualityControlCompanyId = collect(self::qualityControlCompanyList('', 0))->pluck('id')->toArray();

        $list = collect($paginate->items())->map(function ($fsCompanyUserModel) use (&$companyIds, $userInfo, $qualityControlCompanyId) {
            $tempCompanyIds = [];
            if (count($fsCompanyUserModel->fsCompanyUserMappingRel)) {
                foreach ($fsCompanyUserModel->fsCompanyUserMappingRel as $fsCompanyUserMappingModel) {
                    if (!in_array($fsCompanyUserMappingModel->fsCompanyId, $qualityControlCompanyId)) {
                        continue;
                    }
                    $companyIds[]     = $fsCompanyUserMappingModel->fsCompanyId;
                    $tempCompanyIds[] = $fsCompanyUserMappingModel->fsCompanyId;
                }
            }

            return [
                'companyIds'      => $tempCompanyIds,
                'userId'          => $fsCompanyUserModel->rmsUserId,
                // 'username'        => $userInfo[$fsCompanyUserModel->rmsUserId]['username'],
                'username'        => $fsCompanyUserModel->name,
                'mobile'          => $fsCompanyUserModel->phone,
                'status'          => $userStatus = $userInfo[$fsCompanyUserModel->rmsUserId]['status'],
                'statusText'      => $userStatus == 0 ? '正常' : '停用',
                'createdAt'       => $fsCompanyUserModel->createdAt->toDateTimeString(),
            ];

        })->toArray();

        $companyInfo = FsCompanyModel::query()
            ->whereIn('id', array_unique($companyIds))
            ->where('organizationId', FsCompanyModel::WEB_ORGANIZATION_ID)
            ->pluck('name', 'id')
            ->toArray();

        return [
            'list'     => collect($list)->map(function ($item) use ($companyInfo) {
                $company = [];
                foreach ($item['companyIds'] as $companyId) {
                    if (!isset($companyInfo[$companyId]) || !strlen($companyInfo[$companyId])) {
                        continue;
                    }
                    $company[] = [
                        'id'   => $companyId,
                        'name' => $companyInfo[$companyId],
                    ];
                }
                $item['companyList'] = $company;
                return $item;
            }),
            'count'    => $paginate->total(),
            'pageNum'  => $pageNum,
            'pageSize' => $pageSize,
        ];
    }

    /**
     * 获得公司列表
     * @param string $name
     * @param int $status 默认获得启用的供应商
     * @return array
     */
    public static function qualityControlCompanyList(string $name = '', int $status = 1): array
    {
        $searchName = true;
        if (!strlen($name)) {
            $searchName = false;
            $name       = 'all';
        }

        // 缓存30天 如果有新增的供应商 删除tag
        $list = Cache::tags('quality_control_company_list')->remember('tiger:quality_control_company_list:' . $name . $status, 30 * 86400, function () use ($name, $searchName, $status) {
            return FsCompanyModel::query()
                ->when($searchName, function ($query) use ($name) {
                    $query->where('name', 'like', "%$name%");
                })
                ->when($status, function ($query) use ($status) {
                    $query->where('status', $status);
                })
                ->where('organizationId', FsCompanyModel::WEB_ORGANIZATION_ID)
                ->pluck('name', 'id')
                ->toArray();
        });

        return collect($list)->map(function ($item, $key) {
            return [
                'id'   => $key,
                'name' => $item
            ];
        })->values()->toArray();
    }

    /**
     * 添加、编辑员工信息
     * @param int $userId
     * @param array $companyIds
     * @param string $username
     * @param string $mobile
     * @param string $password
     * @param int $status
     * @return void
     * @throws GuzzleException
     */
    public static function saveStaffInfo(int $userId, array $companyIds, string $username, string $mobile, string $password, int $status)
    {
        // 判断有无异常的供应商
        $stopBusinessCompanyExist = FsCompanyModel::query()
            ->whereIn('id', $companyIds)
            ->where('status', FsCompanyModel::STATUS_OFF)
            ->exists();

        if ($stopBusinessCompanyExist) {
            self::throwErr('存在已停用的品控服务商，请刷新后重试', 400);
        }

        if ($userId) {
            // 获得该用户已拥有的供应商
            $haveFsCompanyIds = FsCompanyUserMappingModel::query()
                ->where('rmsUserId', $userId)
                ->pluck('fsCompanyId')
                ->toArray();

            sort($haveFsCompanyIds);
            sort($companyIds);

            // 判断当前用户是否是其他品控服务商的审核人
            $auditFsCompanyIds = FsCompanyRoleMappingModel::query()
                ->where('roleId', FsCompanyRoleMappingModel::ROLE_ID_COMPANY_FIRST)
                ->where('rmsUserId', $userId)
                ->pluck('fsCompanyId')
                ->toArray();

            if (count($auditFsCompanyIds) && $haveFsCompanyIds != $companyIds) {
                $companyNames = FsCompanyModel::query()
                    ->whereIn('id', $auditFsCompanyIds)
                    ->pluck('name')
                    ->toArray();
                self::throwErr('用户属于 ' . implode('、', $companyNames) . ' 审核人，请取消审核人身份后重新修改', 400);
            }

            // 判断当前用户是否存在未完成的任务（待提交-待审核-待修改）
            $fsCompanyDepartmentIds = FsCompanyModel::query()
                ->whereIn('id', $haveFsCompanyIds)
                ->pluck('departmentId')
                ->toArray();

            // 获得进行中的供应商任务信息
            $orderIds = CruiseCheckDetailModel::query()
                ->whereIn('companyId', $fsCompanyDepartmentIds)
                ->where('dealUid', $userId)
                ->where('reportResult', CruiseCheckDetailModel::REPORT_RESULT_INIT)
                ->pluck('orderId')
                ->toArray();

            // 判断是否存在
            $existUnfinished = CruiseOrderModel::query()
                ->whereIn('id', $orderIds)
                ->whereIn('status', [CruiseOrderModel::STATUS_NOT_SUBMIT, CruiseOrderModel::STATUS_NOT_MODIFY, CruiseOrderModel::STATUS_WAIT_MODIFY_EXT, CruiseOrderModel::STATUS_NOT_REVIEW])
                ->exists();

            if ($existUnfinished && $haveFsCompanyIds != $companyIds) {
                self::throwErr('用户存在未完成的任务，请完成后修改', 400);
            }
        } else {
            // 判断用户是否存在
            $existCompanyUser = FsCompanyUserModel::query()
                ->where('phone', $mobile)
                ->exists();

            if ($existCompanyUser) {
                self::throwErr('用户已存在，请进行修改', 400);
            }
        }

        // 获取公司信息
        $companyInfo = [];
        FsCompanyModel::query()
            ->whereIn('id', $companyIds)
            ->select(['id', 'departmentId', 'name'])
            ->get()
            ->map(function (FsCompanyModel $fsCompanyModel) use (&$companyInfo) {
                $companyInfo[] = [
                    'id'           => $fsCompanyModel->id,
                    'name'         => $fsCompanyModel->departmentId,
                    'departmentId' => $fsCompanyModel->name,
                ];
            });

        $response = RmsUserRemote::importSupplierCruiseStaff([
            [
                'id'       => $userId,
                'username' => $username,
                'mobile'   => $mobile,
                'password' => $password,
                'status'   => $status,
            ]
        ]);

        // 只会循环一次
        foreach ($response as $userInfo) {
            // // 删除员工已有
            // FsCompanyUserModel::query()
            //     ->join('fs_company', 'fs_company.departmentId', '=', 'fs_company_users.supplierDepartmentId')
            //     ->where('fs_company.organizationId', FsCompanyModel::WEB_ORGANIZATION_ID)
            //     ->where('rmsUserId', $userInfo['userId'])
            //     ->delete();

            // 获取已有的fs_company_id
            $haveFsCompanyIds = FsCompanyUserMappingModel::query()
                ->whereIn('fsCompanyId', collect(self::qualityControlCompanyList())->pluck('id')->toArray())
                ->where('rmsUserId', $userInfo['userId'])
                ->pluck('fsCompanyId')
                ->toArray();

            // 获取要删除的fs_company_id
            $delFsCompanyIds = array_diff($haveFsCompanyIds, $companyIds);

            FsCompanyUserMappingModel::query()
                ->whereIn('fsCompanyId', $delFsCompanyIds)
                ->where('rmsUserId', $userInfo['userId'])
                ->delete();

            foreach ($companyInfo as $companyItem) {
                // 添加新的
                $fsCompanyUserModel = FsCompanyUserModel::query()
                    ->updateOrCreate([
                        'rmsUserId'              => $userInfo['userId'],
                        'phone'                  => $userInfo['mobile'],
                        'ext'                    => FsCompanyUserModel::EXT_OUT,
                    ]);
                $fsCompanyUserModel->name   = $userInfo['username'];
                $fsCompanyUserModel->source = FsCompanyUserModel::SOURCE_QUALITY_CONTROL;
                $fsCompanyUserModel->save();

                $fsCompanyUserMappingModel = FsCompanyUserMappingModel::query()
                    ->updateOrCreate([
                        // 'fsCompanyId' => $companyItem['id'], 只允许存在一个供应商
                        'rmsUserId'   => $userInfo['userId'],
                        'feishuId'    => '',
                    ]);

                $fsCompanyUserMappingModel->fsCompanyId = $companyItem['id'];
                $fsCompanyUserMappingModel->save();

            }

        }
    }


    // 获得属于品控服务商的用户列表
    public static function getQualityControlStaffList(int $companyId = 0): array
    {
        $fsCompanyIds = FsCompanyModel::query()
            ->when($companyId, function ($query) use ($companyId) {
                $query->where('id', $companyId);
            })
            ->where('status', FsCompanyModel::STATUS_ON)
            ->where('organizationId', FsCompanyModel::WEB_ORGANIZATION_ID)
            ->pluck('id')
            ->toArray();

        return FsCompanyUserMappingModel::query()
            ->whereIn('fsCompanyId', $fsCompanyIds)
            ->groupBy('rmsUserId')
            ->pluck('rmsUserId')
            ->toArray();
    }

    /**
     * 修改员工状态
     * @throws GuzzleException
     */
    public static function updateStaffStatus(int $userId, int $status)
    {
        RmsUserRemote::importSupplierCruiseStaff([
            [
                'id'       => $userId,
                'status'   => $status,
            ]
        ]);
    }
}
